unit KolmogorovPlot;

interface
uses DiagramFactory, datacontainer, pganalysistypesunit, apgabstractunit, classes,
   xmlintf, pgseriesunit, chartaxisunit, ifmmemoryunit, math, ifmgdi, sysutils;

type
   KolDiagram = class(TasacsDiagram)
   public
      constructor Create(AOwner : TComponent; _ds : integer; datacontainer : TasacsDataContainer); reintroduce;
   end;

   KolChart = class(DSChart)
//      function NumUndefinedElmsOnModAxis : Integer;
   public
      function CreateChartAxis(Axis : PgAxisType) : APgChartAxis; override;
      function CreateSeries(AOwner : TComponent; PrimaryChartAxis : APgChartAxis; MetaSeries : APgMetaSeries; XIndex : Integer) : APgSeries; override;
      constructor Create(AOwner : TComponent; datacontainer : TasacsDataContainer; _Ds : Integer); reintroduce;
   end; // KolChart


   KolSeries = class(PgSeries)
   protected
      function GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double; override;
      function GetShowZeros() : Boolean; override;
   end; // KolSeries


   QModAxis = class(PgChartAxis)
   protected
      function GetNumDimensionElms : Integer; override;
      function GetAxisLabel : string; override;
      function GetIntervalSeriesHeader : string; override;
   end; // QModAxis


   QModAxisSeries = class(TasacsAxisSeries)
   protected
      function GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double; override;
   end; // QModAxisSeries


implementation


///////////////////////////////
// KolDiagram


constructor KolDiagram.Create(AOwner : TComponent; _ds : Integer; datacontainer : TasacsDataContainer);
begin
   inherited Create(AOwner, nil, DataSourceContainer(DataContainer.Ds[_Ds]).Key, 'Kolmogorov',
      DataSourceContainer(DataContainer.Ds[_Ds]).Name, datacontainer);
   ShowSubTitle1 := true;
   UseDefSubTitle1 := false;
   SubTitle1 := 'Kolmogorov criteria: ' + floattostr(roundto(datasourcecontainer(datacontainer.Ds[_ds]).KolCriteria, -4));
   NumDiagramColumns := 1;
   UseDefDiagramColumns := false;
end; // KolDiagram.Create


//////////////////////////////////
// KolChart


function KolChart.CreateChartAxis(Axis : PgAxisType) : APgChartAxis;
begin
   case Axis of
      atx:
         Result := QModAxis.Create(Self as IChart, Axis);
   else
      Result := PgChartAxis.Create(Self as IChart, Axis);
   end; // case
end; // KolChart.CreateChartAxis


function KolChart.CreateSeries(AOwner : TComponent; PrimaryChartAxis : APgChartAxis; MetaSeries : APgMetaSeries; XIndex : Integer) : APgSeries;
begin
   Result := nil;
   case PrimaryChartAxis.axis of
      atX:
         if Assigned(MetaSeries) then
           Result := KolSeries.Create(AOwner, PrimaryChartAxis, MetaSeries, XIndex)
         else
            Result := QModAxisSeries.Create(AOwner, PrimaryChartAxis, MetaSeries, XIndex);
   end; // case
end; // KolChart.CreateSeries


constructor KolChart.Create(AOwner : TComponent; datacontainer : TasacsDataContainer; _Ds : Integer);
var
   M : APgMetaSeries;
begin
   inherited Create(AOwner, datacontainer, _DS);
   Self.Caption := Caption;
   ShowSeriesLegend := false;
   ShowMeanLegend := false;
//      ChartAxis[atX].ShowIntervalSeries := true;
   PlotType := ptCategorySingle;

   chartaxis[atx].AxisLabelPosition := alpHigh;
   chartaxis[atX].ContinuousGroupData := false;
   chartaxis[atX].AxisSeriesPosition := aspInside;
   chartaxis[atX].ShowMinorTick := false;
   chartaxis[atX].ShowMajorTick := false;
   chartaxis[atx].DefaultMin := false;
   chartaxis[atx].MinValue := 0;
   chartaxis[atx].Direction := north;
   chartaxis[atx].ShowIntervalSeries := true;
   chartaxis[aty].Direction := east;
//   chartaxis[atx].LnTransformed := true;
   //chartaxis[atX].AxisLabelPosition := alpCenter;
   chartaxis[atX].ShowMajorGrid := false;
   chartaxis[aty].AxisLabel := '# Obs < Mod';
   chartaxis[aty].AxisLabelPosition := alpHigh;
   chartaxis[aty].DefaultAxisLabel := false;
   chartaxis[aty].DefaultMin := false;
   chartaxis[aty].MinValue := 0;
   chartaxis[atx].DefNumDecimals := false;
   chartaxis[atx].NumDecimals := 3;
 //  chartaxis[aty].LnTransformed := true;
   // Setup meta series at y axis:
   with ChartAxis[atY].MetaSeries do
   begin
      M := TasacsMetaSeries.Create(ChartAxis[aty], nil, '# Obs < Mod', 0);
      M.Scatter := true;
      M.BarPlot := false;
      Add(Pointer(M));
   end;
end; // KolChart.Create


{function KolChart.NumUndefinedElmsOnModAxis : Integer;
var
   I : Integer;
   f : FloatArray;
begin
   Result := 0;
   f := FloatArray(DataSourceContainer(DataContainer.DS[DS]).DsData[ord(dsModSorted)]);
   for I := 0 to f.Capacity - 1 do
      if f[I] > 0 then
      begin
         Result := Result + 1;
         break;
      end;
end; // KolChart.NumUndefinedElmsOnModAxis}


///////////////////////////////
// KolSeries


function KolSeries.GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double;
begin
   with KolChart(PrimaryChartAxis.ChartComp) do
   case SeriesVariable of
      svIntervalDelta:
      begin
         Result := FloatArray(DataSourceContainer(Datacontainer.DS[DS]).DsData[ord(dsNObsLessThanMod)])[MinCategory + I];
      end
   else
      Result := inherited GetInternalValue(I, SeriesVariable, MetaSeries)
   end; // case
end; // KolSeries.GetInternalValue


function KolSeries.GetShowZeros() : Boolean;
begin
   Result := false;
end;


///////////////////
// QModAxis


function QModAxis.GetAxisLabel : string;
begin
   if DefaultAxisLabel then
      Result := 'Rank'
   else
      Result := inherited GetAxisLabel;
end; // QModAxis.GetAxisLabel


function QModAxis.GetNumDimensionElms : Integer;
begin
   with KolChart(ChartComp) do
      Result := FloatArray(DataSourceContainer(DataContainer.DS[DS]).DsData[ord(dsModSorted)]).Capacity;
end; // QModAxis.GetNumDimensionElms


function QModAxis.GetIntervalSeriesHeader : string;
begin
   Result := 'Modelled';
end;


function QModAxisSeries.GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double;
begin
   Assert(IsAxisSeries);
   with KolChart(PrimaryChartAxis.ChartComp) do
   case SeriesVariable of
      svUserInterval:
      begin
         Result := FloatArray(DataSourceContainer(Datacontainer.DS[DS]).DsData[ord(dsModSorted)])[MinCategory + I];
         if Result < 0 then
            Result := nan
      end
   else
      Result := inherited GetInternalValue(I, SeriesVariable, MetaSeries);
   end; // case
end; // QModAxisSeries.GetInternalValue


end.
